package com.wentao.thisService.service.impl;

import com.wentao.thisCommon.common.SnowFlake;
import com.wentao.thisFacade.common.enums.ExceptionCode;
import com.wentao.thisFacade.common.enums.business.HotelReviewStatusEnum;
import com.wentao.thisFacade.common.enums.business.OrderFormCode;
import com.wentao.thisFacade.common.enums.business.PayCode;
import com.wentao.thisFacade.common.enums.business.ValidStatusEnum;
import com.wentao.thisFacade.common.exception.CustomException;
import com.wentao.thisFacade.domain.PageBase;
import com.wentao.thisFacade.domain.reqeust.CreateOrderInfoListRequest;
import com.wentao.thisFacade.domain.reqeust.CreateOrderInfoRequest;
import com.wentao.thisFacade.domain.reqeust.OrderDeliverRequest;
import com.wentao.thisFacade.domain.reqeust.OrderPayRequest;
import com.wentao.thisFacade.domain.result.CompanyAddressInfoResult;
import com.wentao.thisFacade.domain.result.GoodsInfoResult;
import com.wentao.thisFacade.domain.result.OrderInfoPageResult;
import com.wentao.thisFacade.domain.result.OrderInfoResult;
import com.wentao.thisService.common.CommonFunction;
import com.wentao.thisService.common.TokenVerify;
import com.wentao.thisService.mapper.*;
import com.wentao.thisService.model.*;
import com.wentao.thisService.model.entities.IntResultEntity;
import com.wentao.thisService.service.CommunalService;
import com.wentao.thisService.service.GoodsService;
import com.wentao.thisService.service.OrderService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.util.*;

/**
 * @Auther: ZhaiYanTao
 * @Date: 2020/3/27 10:17
 * @Description: 订单service实现
 */
@Service
public class OrderServiceImpl implements OrderService {

    @Value("${readFile.host.ip}")
    private String readFileHostIp;

    @Autowired
    private CommunalService communalService;

    @Autowired
    private GoodsService goodsService;

    @Autowired
    private CommonDao commonDao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private SettingMapDao settingMapDao;

    @Autowired
    private CompanyCustomDao companyCustomDao;

    @Autowired
    private AddressDao addressDao;

    @Autowired
    private GoodsPriceInfoDao goodsPriceInfoDao;

    @Autowired
    private PayDao payDao;

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private OrderGoodsDao orderGoodsDao;

    @Autowired
    private GoodsDao goodsDao;

    /**
     * @see OrderService#createOrderInfo(CreateOrderInfoListRequest, Long)
     */
    @Override
    @TokenVerify
    public OrderInfoResult createOrderInfo(CreateOrderInfoListRequest createOrderInfoListRequest, Long userId) throws Exception {
        Timestamp nowTimestamp = commonDao.getNowTime();
        String nowTimeString = CommonFunction.GetDateByTime(nowTimestamp.getTime());

        // 下单商品列表
        List<CreateOrderInfoRequest> requestGoodsList = createOrderInfoListRequest.getCreateOrderInfoList();
        if (null == requestGoodsList || requestGoodsList.size() == 0) {
            throw new CustomException(ExceptionCode.ORDER_NO_GOODS_ERROR);
        }

        // 获取是否是测试支付
        boolean isTestPay = true;
        SettingMapEntity searchPayType = new SettingMapEntity();
        searchPayType.setGroupCode("BASE_CODE");
        searchPayType.setGroupType("PAY_TYPE");
        searchPayType.setKeyCode("TEST");
        List<SettingMapEntity> payTypeSettingResult = settingMapDao.Search(searchPayType);
        if (null != payTypeSettingResult && payTypeSettingResult.size() > 0) {
            if ("N".equals(payTypeSettingResult.get(0).getStatus())) {
                // status设置为N，表示关闭测试支付配置项
                isTestPay = false;
            }
        }

        // 获取酒店信息
        CompanyCustomEntity searchCompanyCustom = new CompanyCustomEntity();
        searchCompanyCustom.setUserId(userId);
        List<CompanyCustomEntity> companyCustomEntityList = companyCustomDao.Search(searchCompanyCustom);
        if (null == companyCustomEntityList || companyCustomEntityList.size() == 0) {
            throw new CustomException(ExceptionCode.NOCOMPANY_ERROR);
        }
        searchCompanyCustom = companyCustomEntityList.get(0);

        // 获取商品信息
        Map<Long, Integer> goodsIdNumMap = new HashMap<>();
        for (CreateOrderInfoRequest createOrderInfoRequest : requestGoodsList) {
            if (null != createOrderInfoRequest) {
                if (!goodsIdNumMap.containsKey(createOrderInfoRequest.getId())) {
                    goodsIdNumMap.put(createOrderInfoRequest.getId(), createOrderInfoRequest.getQuantity());
                } else {
                    goodsIdNumMap.put(createOrderInfoRequest.getId(), createOrderInfoRequest.getQuantity() + goodsIdNumMap.get(createOrderInfoRequest.getId()));
                }
            }
        }

        GoodsPriceInfoEntity searchGoodsPrice = new GoodsPriceInfoEntity();
        searchGoodsPrice.setIdLIST(new ArrayList<>(goodsIdNumMap.keySet()));
        List<GoodsPriceInfoEntity> goodsPriceInfoEntityList = goodsPriceInfoDao.Search(searchGoodsPrice);
        if (null == goodsPriceInfoEntityList || goodsPriceInfoEntityList.size() == 0) {
            throw new CustomException(ExceptionCode.NO_GOODS_ERROR);
        }
        Map<Long, GoodsPriceInfoEntity> deDuplicationMap = new HashMap<>();
        for (GoodsPriceInfoEntity goodsPriceInfoEntity : goodsPriceInfoEntityList) {
            if (null != goodsPriceInfoEntity) {
                deDuplicationMap.put(goodsPriceInfoEntity.getId(), goodsPriceInfoEntity);
            }
        }
        goodsPriceInfoEntityList = new ArrayList<>(deDuplicationMap.values());

        // 金额计算
        long totalPrice = 0L;
        long totalDiscount = 0L;
        long totalFare = 0L;
        int totalNum = 0;
        StringBuilder orderContent = new StringBuilder();
        for (GoodsPriceInfoEntity goodsPriceInfoEntity : goodsPriceInfoEntityList) {
            if (null != goodsPriceInfoEntity) {
                int goodsNum = null == goodsIdNumMap.get(goodsPriceInfoEntity.getId()) ? 0 : goodsIdNumMap.get(goodsPriceInfoEntity.getId());
                totalPrice += (null == goodsPriceInfoEntity.getPrice() ? 0 : goodsPriceInfoEntity.getPrice()) * goodsNum;
                totalDiscount += (null == goodsPriceInfoEntity.getDiscount() ? 0 : goodsPriceInfoEntity.getDiscount()) * goodsNum;
                totalFare += (null == goodsPriceInfoEntity.getFare() ? 0 : goodsPriceInfoEntity.getFare()) * goodsNum;
                totalNum += goodsNum;
                orderContent.append(String.format("%s*%s%s", goodsPriceInfoEntity.getName(), goodsNum, goodsPriceInfoEntity.getUnit()));
                if (goodsPriceInfoEntityList.indexOf(goodsPriceInfoEntity) == goodsPriceInfoEntityList.size() - 1) {
                    orderContent.append(".");
                } else {
                    orderContent.append(";");
                }
            }
        }

        // 判断用户是否已完成酒水采购任务
        CompanyAddressInfoResult companyAddressInfoResult = communalService.hotelReviewStatus(searchCompanyCustom.getCompanyCode());
        String hotelReviewStatus = companyAddressInfoResult.getRemark();
        if (!HotelReviewStatusEnum.BUYING_TASK_COMPLETED.getCode().equals(hotelReviewStatus) && totalDiscount < 100000) {
            throw new CustomException(ExceptionCode.REQUIRED_PAYMENT_NOT_ENOUGH);
        }

        // 保存支付信息
        PayEntity savePay = new PayEntity();
        savePay.setPayType(PayCode.WECHAT_PAY.getCode());
        savePay.setTotalPrice(totalDiscount);
        savePay.setRealPrice(isTestPay ? 1 : totalDiscount + totalFare);
        savePay.setPayNumber(Integer.toString(totalNum));
        savePay.setPayStatus(PayCode.WAITING_FOR_PAYMENT.getCode());
        savePay.setReason(isTestPay ? "测试支付仅支付0.01元" : null);
        savePay.setStatus("Y");
        savePay.setOwnId(userId);
        savePay.setCreateTime(nowTimeString);
        payDao.Insert(savePay);

        // 保存订单信息
        SnowFlake snowFlake = new SnowFlake();
        Long orderNumber = snowFlake.orderNumber();
        OrderEntity saveOrder = new OrderEntity();
        saveOrder.setOrderNumber(String.valueOf(orderNumber.toString()));
        saveOrder.setDeliveryType(createOrderInfoListRequest.getDeliveryType());
        saveOrder.setTitle(createOrderInfoListRequest.getTitle());
        saveOrder.setContent(orderContent.toString());
        saveOrder.setPrice(totalPrice);
        saveOrder.setTotal(totalPrice + totalFare);
        saveOrder.setUserId(userId);
        saveOrder.setContractNumber(searchCompanyCustom.getContact());
        saveOrder.setDiscount(totalDiscount + totalFare);
        saveOrder.setPayId(savePay.getId());
        saveOrder.setOrderTime(nowTimeString);
        // TODO: 2020/3/27 新版地址信息location获取:address存地址详情，location存定位adcode
        saveOrder.setAddress(String.format("%s %s ", searchCompanyCustom.getLocation(), searchCompanyCustom.getAddress()));
        saveOrder.setOrderStatus(OrderFormCode.ORDER_ENTRY_COMPLETED.getCode());
        saveOrder.setStatus("Y");
        saveOrder.setOwnId(userId);
        saveOrder.setOrderSource("APP订单");
        saveOrder.setCreateTime(nowTimeString);
        orderDao.Insert(saveOrder);

        // 保存订单商品
        for (GoodsPriceInfoEntity goodsPriceInfoEntity : goodsPriceInfoEntityList) {
            if (null != goodsPriceInfoEntity) {
                OrderGoodsEntity saveOrderGoods = new OrderGoodsEntity();
                saveOrderGoods.setTitle(createOrderInfoListRequest.getTitle());
                saveOrderGoods.setOrderId(saveOrder.getId());
                saveOrderGoods.setGoodsId(goodsPriceInfoEntity.getId());
                saveOrderGoods.setQuantity(goodsIdNumMap.get(goodsPriceInfoEntity.getId()));
                saveOrderGoods.setPrice(goodsPriceInfoEntity.getPrice());
                saveOrderGoods.setDiscount(goodsPriceInfoEntity.getDiscount());
                saveOrderGoods.setFare(goodsPriceInfoEntity.getFare());
                saveOrderGoods.setWeight(goodsPriceInfoEntity.getWeight());
                saveOrderGoods.setVolume(goodsPriceInfoEntity.getVolume());
                saveOrderGoods.setRemark(String.format("[%s]订购了[%s]", searchCompanyCustom.getCompanyName(), goodsPriceInfoEntity.getName()));
                saveOrderGoods.setStatus("Y");
                saveOrderGoods.setOwnId(userId);
                saveOrderGoods.setCreateTime(nowTimeString);
                orderGoodsDao.Insert(saveOrderGoods);
            }
        }

        // 返回订单结果
        List<GoodsInfoResult> goodsInfoList = goodsService.goodsList();
        if (null != goodsInfoList && goodsInfoList.size() > 0) {
            for (GoodsInfoResult goodsInfoResult : goodsInfoList) {
                if (null != goodsInfoResult) {
                    goodsInfoResult.setGoodsNumForOrder(goodsIdNumMap.get(Long.valueOf(goodsInfoResult.getId())));
                }
            }
        }
        OrderInfoResult orderInfoResult = new OrderInfoResult();
        orderInfoResult.setGoodsInfoList(goodsInfoList);
        orderInfoResult.setOrderId(String.valueOf(saveOrder.getId()));
        orderInfoResult.setOrderTime(saveOrder.getOrderTime());
        orderInfoResult.setUserAccount(saveOrder.getContractNumber());
        orderInfoResult.setOrderSource(saveOrder.getOrderSource());
        orderInfoResult.setOrderStatus(saveOrder.getOrderStatus());
        orderInfoResult.setPayType(savePay.getPayType());
        orderInfoResult.setPayTime(savePay.getPayTime());
        // TODO: 2020/3/27 location adcode转文字信息
        orderInfoResult.setLocation(searchCompanyCustom.getLocation());
        orderInfoResult.setAddress(searchCompanyCustom.getAddress());
        orderInfoResult.setCompanyName(searchCompanyCustom.getCompanyName());
        orderInfoResult.setCompanyContact(searchCompanyCustom.getCompanyContact());
        orderInfoResult.setTotalDiscount(totalDiscount);
        orderInfoResult.setTotalFare(totalFare);
        orderInfoResult.setPaymentAmount(savePay.getRealPrice());

        return orderInfoResult;

    }

    /**
     * @see OrderService#listOrderByUserId(Long)
     */
    @Override
    @TokenVerify
    public List<OrderInfoResult> listOrderByUserId(Long userId) throws Exception {

        Map<String, OrderInfoResult> orderInfoResultMap = new HashMap<>();

        // 酒店信息
        CompanyCustomEntity searchCompanyCustom = new CompanyCustomEntity();
        searchCompanyCustom.setUserId(userId);
        List<CompanyCustomEntity> companyCustomEntityList = companyCustomDao.Search(searchCompanyCustom);
        if (null == companyCustomEntityList || companyCustomEntityList.size() == 0) {
            throw new CustomException(ExceptionCode.NOCOMPANY_ERROR);
        }
        searchCompanyCustom = companyCustomEntityList.get(0);

        // 订单商品信息
        OrderGoodsEntity searchOrderGoods = new OrderGoodsEntity();
        searchOrderGoods.setOwnId(userId);
        List<OrderGoodsEntity> orderGoodsEntityList = orderGoodsDao.Search(searchOrderGoods);
        if (null != orderGoodsEntityList && orderGoodsEntityList.size() > 0) {
            Set<Long> orderIdSet = new HashSet<>();
            Set<Long> goodsIdSet = new HashSet<>();
            Map<Long, Map<Long, Integer>> orderIdGoodsIdNumMapMap = new HashMap<>();
            for (OrderGoodsEntity orderGoodsEntity : orderGoodsEntityList) {
                if (null != orderGoodsEntity) {
                    orderIdSet.add(orderGoodsEntity.getOrderId());
                    goodsIdSet.add(orderGoodsEntity.getGoodsId());
                    if (!orderIdGoodsIdNumMapMap.containsKey(orderGoodsEntity.getOrderId())) {
                        Map<Long, Integer> innerGoodsIdNumMap = new HashMap<>();
                        innerGoodsIdNumMap.put(orderGoodsEntity.getGoodsId(), orderGoodsEntity.getQuantity());
                        orderIdGoodsIdNumMapMap.put(orderGoodsEntity.getOrderId(), innerGoodsIdNumMap);
                    } else {
                        Map<Long, Integer> innerGoodsIdNumMap = orderIdGoodsIdNumMapMap.get(orderGoodsEntity.getOrderId());
                        if (!innerGoodsIdNumMap.containsKey(orderGoodsEntity.getGoodsId())) {
                            innerGoodsIdNumMap.put(orderGoodsEntity.getGoodsId(), orderGoodsEntity.getQuantity());
                        } else {
                            innerGoodsIdNumMap.put(orderGoodsEntity.getGoodsId(), innerGoodsIdNumMap.get(orderGoodsEntity.getGoodsId()) + orderGoodsEntity.getQuantity());
                        }
                        orderIdGoodsIdNumMapMap.put(orderGoodsEntity.getOrderId(), innerGoodsIdNumMap);
                    }
                }
            }

            // 订单信息
            List<Long> orderIdList = new ArrayList<>(orderIdSet);
            if (orderIdList.size() == 0) {
                orderIdList.add(0L);
            }
            List<OrderEntity> orderEntityList = orderDao.SearchByOrderIdList(orderIdList);
            Map<Long, OrderEntity> orderIdEntityMap = new HashMap<>();
            Set<Long> payIdSet = new HashSet<>();
            if (null != orderEntityList && orderEntityList.size() > 0) {
                for (OrderEntity orderEntity : orderEntityList) {
                    if (null != orderEntity) {
                        orderIdEntityMap.put(orderEntity.getId(), orderEntity);
                        payIdSet.add(orderEntity.getPayId());
                    }
                }
            }

            // 商品信息
            List<Long> goodsIdList = new ArrayList<>(goodsIdSet);
            if (goodsIdList.size() == 0) {
                goodsIdList.add(0L);
            }
            List<Map<String, Object>> goodsInfoMapList = goodsDao.SearchGoodsInfoByGoodsIdList(goodsIdList);
            List<GoodsInfoResult> goodsInfoResultList = transformMapToGoodsInfoList(goodsInfoMapList);
            Map<String, GoodsInfoResult> goodsIdInfoResultMap = new HashMap<>();
            if (null != goodsInfoMapList && goodsInfoMapList.size() > 0) {
                for (GoodsInfoResult goodsInfoResult : goodsInfoResultList) {
                    if (null != goodsInfoResult) {
                        goodsIdInfoResultMap.put(goodsInfoResult.getId(), goodsInfoResult);
                    }
                }
            }

            Map<Long, List<GoodsInfoResult>> orderIdGoodsInfoResultListMap = new HashMap<>();
            if (orderIdSet.size() > 0) {
                for (Long orderId : orderIdSet) {
                    Map<Long, Integer> orderGoodsIdNumMap = orderIdGoodsIdNumMapMap.get(orderId);
                    if (null != orderGoodsIdNumMap && !orderGoodsIdNumMap.isEmpty()) {
                        for (Long goodsId : orderGoodsIdNumMap.keySet()) {
                            GoodsInfoResult goodsInfoResult = new GoodsInfoResult();
                            BeanUtils.copyProperties(goodsIdInfoResultMap.get(String.valueOf(goodsId)), goodsInfoResult);
                            goodsInfoResult.setGoodsNumForOrder(orderGoodsIdNumMap.get(Long.valueOf(goodsInfoResult.getId())));
                            if (!orderIdGoodsInfoResultListMap.containsKey(orderId)) {
                                List<GoodsInfoResult> innerGoodsInfoResultList = new ArrayList<>();
                                innerGoodsInfoResultList.add(goodsInfoResult);
                                orderIdGoodsInfoResultListMap.put(orderId, innerGoodsInfoResultList);
                            } else {
                                orderIdGoodsInfoResultListMap.get(orderId).add(goodsInfoResult);
                            }
                        }
                    }
                }
            }

            // 支付信息
            List<Long> payIdList = new ArrayList<>(payIdSet);
            if (payIdList.size() == 0) {
                payIdList.add(0L);
            }
            List<PayEntity> payEntityList = payDao.SearchByPayIdList(payIdList);
            Map<Long, PayEntity> payIdEntityMap = new HashMap<>();
            if (null != payEntityList && payEntityList.size() > 0) {
                for (PayEntity payEntity : payEntityList) {
                    if (null != payEntity) {
                        payIdEntityMap.put(payEntity.getId(), payEntity);
                    }
                }
            }

            // 生成订单列表结果集
            OrderInfoResult orderInfoResult;
            for (OrderGoodsEntity orderGoodsEntity : orderGoodsEntityList) {
                OrderEntity orderEntity = orderIdEntityMap.get(orderGoodsEntity.getOrderId());
                PayEntity payEntity = payIdEntityMap.get(orderEntity.getPayId());

                orderInfoResult = new OrderInfoResult();
                orderInfoResult.setGoodsInfoList(null == orderIdGoodsInfoResultListMap.get(orderEntity.getId()) ? new ArrayList<>() : orderIdGoodsInfoResultListMap.get(orderEntity.getId()));
                orderInfoResult.setOrderId(String.valueOf(orderEntity.getId()));
                orderInfoResult.setOrderNumber(orderEntity.getOrderNumber());
                orderInfoResult.setOrderTime(orderEntity.getOrderTime());
                orderInfoResult.setUserAccount(orderEntity.getContractNumber());
                orderInfoResult.setOrderSource(orderEntity.getOrderSource());
                orderInfoResult.setOrderStatus(getOrderStatusForAPPByCode(orderEntity.getOrderStatus()));
                orderInfoResult.setDeliverNumber(orderEntity.getDeliverNumber());
                orderInfoResult.setDeliverCompany(orderEntity.getDeliverCompany());
                orderInfoResult.setPayType(getPayTypeMessageByCode(payEntity.getPayType()));
                orderInfoResult.setPayTime(payEntity.getPayTime());
                // TODO: 2020/3/27 location adcode转文字信息
                orderInfoResult.setLocation(searchCompanyCustom.getLocation());
                orderInfoResult.setAddress(searchCompanyCustom.getAddress());
                orderInfoResult.setCompanyName(searchCompanyCustom.getRegistrant());// 产品要求显示酒店负责人姓名
                orderInfoResult.setCompanyContact(searchCompanyCustom.getContact());// 产品要求显示酒店负责人电话
                orderInfoResult.setTotalDiscount(payEntity.getTotalPrice());
                orderInfoResult.setTotalFare(payEntity.getRealPrice() - payEntity.getTotalPrice() < 0 ? 0 : payEntity.getRealPrice() - payEntity.getTotalPrice());
                orderInfoResult.setPaymentAmount(payEntity.getRealPrice());

                orderInfoResultMap.put(orderInfoResult.getOrderId(), orderInfoResult);
            }
        }

        return new ArrayList<>(orderInfoResultMap.values());
    }

    /**
     * @see OrderService#pageOrder(PageBase)
     */
    @Override
    public OrderInfoPageResult pageOrder(PageBase pageBase) throws Exception {

        Map<String, OrderInfoResult> orderInfoResultMap = new HashMap<>();

        // 酒店信息
        CompanyCustomEntity searchCompanyCustom = new CompanyCustomEntity();
        searchCompanyCustom.setStatus(ValidStatusEnum.VALID.getCode());
        List<CompanyCustomEntity> companyCustomEntityList = companyCustomDao.Search(searchCompanyCustom);
        if (null == companyCustomEntityList || companyCustomEntityList.size() == 0) {
            throw new CustomException(ExceptionCode.NOCOMPANY_ERROR);
        }
        Map<Long, CompanyCustomEntity> userIdCompanyCustomMap = new HashMap<>();
        for (CompanyCustomEntity companyCustomEntity : companyCustomEntityList) {
            if (null != companyCustomEntity) {
                userIdCompanyCustomMap.put(companyCustomEntity.getUserId(), companyCustomEntity);
            }
        }

        // 订单商品信息
        OrderGoodsEntity searchOrderGoods = new OrderGoodsEntity();
        searchOrderGoods.setStatus(ValidStatusEnum.VALID.getCode());
        List<OrderGoodsEntity> orderGoodsEntityList = orderGoodsDao.Search(searchOrderGoods);
        if (null != orderGoodsEntityList && orderGoodsEntityList.size() > 0) {
            Set<Long> orderIdSet = new HashSet<>();
            Set<Long> goodsIdSet = new HashSet<>();
            Map<Long, Map<Long, Integer>> orderIdGoodsIdNumMapMap = new HashMap<>();
            for (OrderGoodsEntity orderGoodsEntity : orderGoodsEntityList) {
                if (null != orderGoodsEntity) {
                    orderIdSet.add(orderGoodsEntity.getOrderId());
                    goodsIdSet.add(orderGoodsEntity.getGoodsId());
                    if (!orderIdGoodsIdNumMapMap.containsKey(orderGoodsEntity.getOrderId())) {
                        Map<Long, Integer> innerGoodsIdNumMap = new HashMap<>();
                        innerGoodsIdNumMap.put(orderGoodsEntity.getGoodsId(), orderGoodsEntity.getQuantity());
                        orderIdGoodsIdNumMapMap.put(orderGoodsEntity.getOrderId(), innerGoodsIdNumMap);
                    } else {
                        Map<Long, Integer> innerGoodsIdNumMap = orderIdGoodsIdNumMapMap.get(orderGoodsEntity.getOrderId());
                        if (!innerGoodsIdNumMap.containsKey(orderGoodsEntity.getGoodsId())) {
                            innerGoodsIdNumMap.put(orderGoodsEntity.getGoodsId(), orderGoodsEntity.getQuantity());
                        } else {
                            innerGoodsIdNumMap.put(orderGoodsEntity.getGoodsId(), innerGoodsIdNumMap.get(orderGoodsEntity.getGoodsId()) + orderGoodsEntity.getQuantity());
                        }
                        orderIdGoodsIdNumMapMap.put(orderGoodsEntity.getOrderId(), innerGoodsIdNumMap);
                    }
                }
            }

            // 订单信息
            List<Long> orderIdList = new ArrayList<>(orderIdSet);
            if (orderIdList.size() == 0) {
                orderIdList.add(0L);
            }
            List<OrderEntity> orderEntityList = orderDao.SearchByOrderIdList(orderIdList);
            Map<Long, OrderEntity> orderIdEntityMap = new HashMap<>();
            Set<Long> payIdSet = new HashSet<>();
            if (null != orderEntityList && orderEntityList.size() > 0) {
                for (OrderEntity orderEntity : orderEntityList) {
                    if (null != orderEntity) {
                        orderIdEntityMap.put(orderEntity.getId(), orderEntity);
                        payIdSet.add(orderEntity.getPayId());
                    }
                }
            }

            // 商品信息
            List<Long> goodsIdList = new ArrayList<>(goodsIdSet);
            if (goodsIdList.size() == 0) {
                goodsIdList.add(0L);
            }
            List<Map<String, Object>> goodsInfoMapList = goodsDao.SearchGoodsInfoByGoodsIdList(goodsIdList);
            List<GoodsInfoResult> goodsInfoResultList = transformMapToGoodsInfoList(goodsInfoMapList);
            Map<String, GoodsInfoResult> goodsIdInfoResultMap = new HashMap<>();
            if (null != goodsInfoMapList && goodsInfoMapList.size() > 0) {
                for (GoodsInfoResult goodsInfoResult : goodsInfoResultList) {
                    if (null != goodsInfoResult) {
                        goodsIdInfoResultMap.put(goodsInfoResult.getId(), goodsInfoResult);
                    }
                }
            }

            Map<Long, List<GoodsInfoResult>> orderIdGoodsInfoResultListMap = new HashMap<>();
            if (orderIdSet.size() > 0) {
                for (Long orderId : orderIdSet) {
                    Map<Long, Integer> orderGoodsIdNumMap = orderIdGoodsIdNumMapMap.get(orderId);
                    if (null != orderGoodsIdNumMap && !orderGoodsIdNumMap.isEmpty()) {
                        for (Long goodsId : orderGoodsIdNumMap.keySet()) {
                            GoodsInfoResult goodsInfoResult = new GoodsInfoResult();
                            BeanUtils.copyProperties(goodsIdInfoResultMap.get(String.valueOf(goodsId)), goodsInfoResult);
                            goodsInfoResult.setGoodsNumForOrder(orderGoodsIdNumMap.get(Long.valueOf(goodsInfoResult.getId())));
                            if (!orderIdGoodsInfoResultListMap.containsKey(orderId)) {
                                List<GoodsInfoResult> innerGoodsInfoResultList = new ArrayList<>();
                                innerGoodsInfoResultList.add(goodsInfoResult);
                                orderIdGoodsInfoResultListMap.put(orderId, innerGoodsInfoResultList);
                            } else {
                                orderIdGoodsInfoResultListMap.get(orderId).add(goodsInfoResult);
                            }
                        }
                    }
                }
            }

            // 支付信息
            List<Long> payIdList = new ArrayList<>(payIdSet);
            if (payIdList.size() == 0) {
                payIdList.add(0L);
            }
            List<PayEntity> payEntityList = payDao.SearchByPayIdList(payIdList);
            Map<Long, PayEntity> payIdEntityMap = new HashMap<>();
            if (null != payEntityList && payEntityList.size() > 0) {
                for (PayEntity payEntity : payEntityList) {
                    if (null != payEntity) {
                        payIdEntityMap.put(payEntity.getId(), payEntity);
                    }
                }
            }

            // 生成订单列表结果集
            OrderInfoResult orderInfoResult;
            for (OrderGoodsEntity orderGoodsEntity : orderGoodsEntityList) {
                OrderEntity orderEntity = orderIdEntityMap.get(orderGoodsEntity.getOrderId());
                PayEntity payEntity = payIdEntityMap.get(orderEntity.getPayId());

                orderInfoResult = new OrderInfoResult();
                orderInfoResult.setGoodsInfoList(null == orderIdGoodsInfoResultListMap.get(orderEntity.getId()) ? new ArrayList<>() : orderIdGoodsInfoResultListMap.get(orderEntity.getId()));
                orderInfoResult.setOrderId(String.valueOf(orderEntity.getId()));
                orderInfoResult.setOrderNumber(orderEntity.getOrderNumber());
                orderInfoResult.setOrderTime(orderEntity.getOrderTime());
                orderInfoResult.setUserAccount(orderEntity.getContractNumber());
                orderInfoResult.setOrderSource(orderEntity.getOrderSource());
                orderInfoResult.setOrderStatus(getOrderStatusForAPPByCode(orderEntity.getOrderStatus()));
                orderInfoResult.setDeliverNumber(orderEntity.getDeliverNumber());
                orderInfoResult.setDeliverCompany(orderEntity.getDeliverCompany());
                orderInfoResult.setPayType(getPayTypeMessageByCode(payEntity.getPayType()));
                orderInfoResult.setPayTime(payEntity.getPayTime());
                // TODO: 2020/3/27 location adcode转文字信息
                orderInfoResult.setLocation(userIdCompanyCustomMap.get(orderGoodsEntity.getOwnId()).getLocation());
                orderInfoResult.setAddress(userIdCompanyCustomMap.get(orderGoodsEntity.getOwnId()).getAddress());
                orderInfoResult.setCompanyName(userIdCompanyCustomMap.get(orderGoodsEntity.getOwnId()).getRegistrant());// 产品要求显示酒店负责人姓名
                orderInfoResult.setCompanyContact(userIdCompanyCustomMap.get(orderGoodsEntity.getOwnId()).getContact());// 产品要求显示酒店负责人电话
                orderInfoResult.setTotalDiscount(payEntity.getTotalPrice());
                orderInfoResult.setTotalFare(payEntity.getRealPrice() - payEntity.getTotalPrice() < 0 ? 0 : payEntity.getRealPrice() - payEntity.getTotalPrice());
                orderInfoResult.setPaymentAmount(payEntity.getRealPrice());

                orderInfoResultMap.put(orderInfoResult.getOrderId(), orderInfoResult);
            }
        }

        // 查总数
        IntResultEntity count = orderGoodsDao.Count(searchOrderGoods);

        OrderInfoPageResult orderInfoPageResult = new OrderInfoPageResult();
        orderInfoPageResult.setRowCount(count.getResult());
        orderInfoPageResult.setOrderInfoResultList(new ArrayList<>(orderInfoResultMap.values()));

        return orderInfoPageResult;
    }


    /**
     * @see OrderService#orderInfo(Long)
     */
    @Override
    @TokenVerify
    public OrderInfoResult orderInfo(Long orderId) throws Exception {
        // 订单商品信息
        OrderGoodsEntity searchOrderGoods = new OrderGoodsEntity();
        searchOrderGoods.setOrderId(orderId);
        List<OrderGoodsEntity> orderGoodsEntityList = orderGoodsDao.Search(searchOrderGoods);
        Map<Long, Integer> goodsIdNumMap = new HashMap<>();
        if (null == orderGoodsEntityList || orderGoodsEntityList.size() == 0) {
            throw new CustomException(ExceptionCode.NO_ORDER_ERROR);
        }
        for (OrderGoodsEntity orderGoodsEntity : orderGoodsEntityList) {
            if (null != orderGoodsEntity) {
                if (!goodsIdNumMap.containsKey(orderGoodsEntity.getGoodsId())) {
                    goodsIdNumMap.put(orderGoodsEntity.getGoodsId(), orderGoodsEntity.getQuantity());
                } else {
                    goodsIdNumMap.put(orderGoodsEntity.getGoodsId(), goodsIdNumMap.get(orderGoodsEntity.getGoodsId()) + orderGoodsEntity.getQuantity());
                }
            }
        }


        // 酒店信息
        CompanyCustomEntity searchCompanyCustom = new CompanyCustomEntity();
        searchCompanyCustom.setUserId(orderGoodsEntityList.get(0).getOwnId());
        List<CompanyCustomEntity> companyCustomEntityList = companyCustomDao.Search(searchCompanyCustom);
        if (null == companyCustomEntityList || companyCustomEntityList.size() == 0) {
            throw new CustomException(ExceptionCode.NOCOMPANY_ERROR);
        }
        searchCompanyCustom = companyCustomEntityList.get(0);

        // 订单信息
        OrderEntity searchOrder = new OrderEntity();
        searchOrder.setId(orderId);
        List<OrderEntity> orderEntityList = orderDao.Search(searchOrder);
        if (null == orderEntityList || orderEntityList.size() == 0) {
            throw new CustomException(ExceptionCode.NO_ORDER_ERROR);
        }
        searchOrder = orderEntityList.get(0);

        // 商品信息
        ArrayList<Long> goodsIdList = new ArrayList<>(goodsIdNumMap.keySet());
        if (goodsIdList.size() == 0) {
            goodsIdList.add(0L);
        }
        List<Map<String, Object>> goodsInfoMapList = goodsDao.SearchGoodsInfoByGoodsIdList(goodsIdList);
        List<GoodsInfoResult> goodsInfoResultList = transformMapToGoodsInfoList(goodsInfoMapList);
        if (goodsInfoResultList.size() > 0) {
            for (GoodsInfoResult goodsInfoResult : goodsInfoResultList) {
                goodsInfoResult.setGoodsNumForOrder(goodsIdNumMap.get(Long.valueOf(goodsInfoResult.getId())));
            }
        }

        // 支付信息
        PayEntity searchPay = new PayEntity();
        searchPay.setId(searchOrder.getPayId());
        List<PayEntity> payEntityList = payDao.Search(searchPay);
        PayEntity payEntity;
        if (null == payEntityList || payEntityList.size() == 0) {
            payEntity = new PayEntity();
        } else {
            payEntity = payEntityList.get(0);
        }

        // 生成订单结果
        OrderInfoResult orderInfoResult = new OrderInfoResult();
        orderInfoResult.setGoodsInfoList(goodsInfoResultList);
        orderInfoResult.setOrderId(String.valueOf(searchOrder.getId()));
        orderInfoResult.setOrderNumber(searchOrder.getOrderNumber());
        orderInfoResult.setOrderTime(searchOrder.getOrderTime());
        orderInfoResult.setUserAccount(searchOrder.getContractNumber());
        orderInfoResult.setOrderSource(searchOrder.getOrderSource());
        orderInfoResult.setOrderStatus(getOrderStatusForAPPByCode(searchOrder.getOrderStatus()));
        orderInfoResult.setDeliverNumber(searchOrder.getDeliverNumber());
        orderInfoResult.setDeliverCompany(searchOrder.getDeliverCompany());
        orderInfoResult.setPayType(getPayTypeMessageByCode(payEntity.getPayType()));
        orderInfoResult.setPayTime(payEntity.getPayTime());
        // TODO: 2020/3/27 location adcode转文字信息
        orderInfoResult.setLocation(searchCompanyCustom.getLocation());
        orderInfoResult.setAddress(searchCompanyCustom.getAddress());
        orderInfoResult.setCompanyName(searchCompanyCustom.getRegistrant());// 产品要求显示酒店负责人姓名
        orderInfoResult.setCompanyContact(searchCompanyCustom.getContact());// 产品要求显示酒店负责人电话
        orderInfoResult.setTotalDiscount(payEntity.getTotalPrice());
        orderInfoResult.setTotalFare(payEntity.getRealPrice() - payEntity.getTotalPrice() < 0 ? 0 : payEntity.getRealPrice() - payEntity.getTotalPrice());
        orderInfoResult.setPaymentAmount(payEntity.getRealPrice());

        return orderInfoResult;
    }

    /**
     * @see OrderService#orderDeliver(OrderDeliverRequest)
     */
    @Override
    public OrderInfoResult orderDeliver(OrderDeliverRequest orderDeliverRequest) throws Exception {
        String orderId = orderDeliverRequest.getOrderId();
        String deliverCompany = orderDeliverRequest.getDeliverCompany();
        String deliverNumber = orderDeliverRequest.getDeliverNumber();
        if (StringUtils.isBlank(orderId)) {
            throw new CustomException(ExceptionCode.ID_NOT_EMPTY);
        }

        // 订单信息
        OrderEntity searchOrder = new OrderEntity();
        searchOrder.setId(Long.valueOf(orderId));
        List<OrderEntity> orderEntityList = orderDao.Search(searchOrder);
        if (null == orderEntityList || orderEntityList.size() == 0) {
            throw new CustomException(ExceptionCode.NO_ORDER_ERROR);
        }
        OrderEntity orderEntity = orderEntityList.get(0);

        // 校验状态值
        if (!OrderFormCode.COMPLETION_OF_PANYMENT.getCode().equals(orderEntity.getOrderStatus())) {
            throw new CustomException(ExceptionCode.ORDER_DELIVER_ERROR);
        }

        // 改变订单状态
        OrderEntity updateValueOrder = new OrderEntity();
        updateValueOrder.setOrderStatus(OrderFormCode.THE_DELIVERY_COMPLETED.getCode());
        updateValueOrder.setDeliverNumber(deliverNumber);
        updateValueOrder.setDeliverCompany(deliverCompany);
        orderDao.Update(orderEntity, updateValueOrder);

        // 查询订单信息返回
        return orderInfo(Long.valueOf(orderId));
    }

    /**
     * @see OrderService#orderConfirmReceived(Long)
     */
    @Override
    @TokenVerify
    public OrderInfoResult orderConfirmReceived(Long orderId) throws Exception {
        // 订单信息
        OrderEntity searchOrder = new OrderEntity();
        searchOrder.setId(orderId);
        List<OrderEntity> orderEntityList = orderDao.Search(searchOrder);
        if (null == orderEntityList || orderEntityList.size() == 0) {
            throw new CustomException(ExceptionCode.NO_ORDER_ERROR);
        }
        OrderEntity orderEntity = orderEntityList.get(0);

        // 校验状态值
        if (!OrderFormCode.THE_DELIVERY_COMPLETED.getCode().equals(orderEntity.getOrderStatus())) {
            throw new CustomException(ExceptionCode.ORDER_CONFIRM_RECEIVED_ERROR);
        }

        // 改变订单状态
        OrderEntity updateValueOrder = new OrderEntity();
        updateValueOrder.setOrderStatus(OrderFormCode.ORDER_CPMPLETION.getCode());
        orderDao.Update(orderEntity, updateValueOrder);

        // 查询订单信息返回
        return orderInfo(orderId);
    }

    /**
     * @see OrderService#changeOrderPayStatus(OrderPayRequest)
     */
    @Override
    @TokenVerify
    public OrderInfoResult changeOrderPayStatus(OrderPayRequest orderPayRequest) throws Exception {
        Long orderId = orderPayRequest.getOrderId();
        String orderStatus = orderPayRequest.getOrderStatus();
        String payStatus = orderPayRequest.getPayStatus();

        // 校验状态值
        List<String> orderStatusList = Arrays.asList(OrderFormCode.COMPLETION_OF_PANYMENT.getCode(), OrderFormCode.ABNORMAL_COMPLETION_ORDER.getCode());
        List<String> payStatusList = Arrays.asList(PayCode.SUCCESSFUL_PAYMENT.getCode(), PayCode.PAYMENT_FAIKURE.getCode());
        if (!orderStatusList.contains(orderStatus)) {
            throw new CustomException(ExceptionCode.ORDER_STATUS_ERROR);
        }
        if (!payStatusList.contains(payStatus)) {
            throw new CustomException(ExceptionCode.PAY_STATUS_ERROR);
        }

        // 设置订单状态
        OrderEntity searchOrder = new OrderEntity();
        searchOrder.setId(orderId);
        List<OrderEntity> orderEntityList = orderDao.Search(searchOrder);
        if (null == orderEntityList || orderEntityList.size() == 0) {
            throw new CustomException(ExceptionCode.NO_ORDER_ERROR);
        }
        OrderEntity orderEntity = orderEntityList.get(0);

        OrderEntity updateValueOrder = new OrderEntity();
        updateValueOrder.setOrderStatus(orderStatus);
        orderDao.Update(orderEntity, updateValueOrder);

        // 设置支付状态
        PayEntity searchPay = new PayEntity();
        searchPay.setId(orderEntity.getPayId());
        List<PayEntity> payEntityList = payDao.Search(searchPay);
        if (null == payEntityList || payEntityList.size() == 0) {
            throw new CustomException(ExceptionCode.NO_PAY_INFO_ERROR);
        }
        PayEntity payEntity = payEntityList.get(0);

        PayEntity updateValuePay = new PayEntity();
        updateValuePay.setPayStatus(payStatus);
        payDao.Update(payEntity, updateValuePay);

        // 查询订单信息返回
        return orderInfo(orderId);
    }

    /**
     * 查询结果map转换为商品信息列表
     *
     * @param goodsInfoMapList 数据库查询结果map
     * @return 商品信息列表
     */
    private List<GoodsInfoResult> transformMapToGoodsInfoList(List<Map<String, Object>> goodsInfoMapList) {
        Map<String, GoodsInfoResult> goodsInfoResultMap = new HashMap<>();
        if (null != goodsInfoMapList && goodsInfoMapList.size() > 0) {
            for (Map<String, Object> stringObjectMap : goodsInfoMapList) {
                Long id = (Long) stringObjectMap.get("id");
                String title = (String) stringObjectMap.get("title");
                String unit = (String) stringObjectMap.get("unit");
                String attributeType = (String) stringObjectMap.get("attributeType");
                String attributeValue = (String) stringObjectMap.get("attributeValue");
                Long price = (Long) stringObjectMap.get("price");
                Long discount = (Long) stringObjectMap.get("discount");

                GoodsInfoResult goodsInfoResult = goodsInfoResultMap.get(id.toString());
                if (null == goodsInfoResult) {
                    goodsInfoResult = new GoodsInfoResult();
                    goodsInfoResult.setId(id.toString());
                    goodsInfoResult.setRotationPictureList(new ArrayList<>());
                    goodsInfoResult.setDetailsPictureList(new ArrayList<>());
                }
                goodsInfoResult.setTitle(title);
                goodsInfoResult.setUnit(unit);
                goodsInfoResult.setOriginalPrice(price);
                goodsInfoResult.setDiscountPrice(discount);
                if ("producingArea".equals(attributeType)) {
                    goodsInfoResult.setProducingArea(attributeValue);
                }
                if ("alcoholContent".equals(attributeType)) {
                    goodsInfoResult.setAlcoholContent(attributeValue);
                }
                if ("storageCondition".equals(attributeType)) {
                    goodsInfoResult.setStorageCondition(attributeValue);
                }
                if ("imported".equals(attributeType)) {
                    goodsInfoResult.setImported(attributeValue);
                }
                if ("notes".equals(attributeType)) {
                    goodsInfoResult.setNotes(attributeValue);
                }
                if ("serialNumber".equals(attributeType)) {
                    goodsInfoResult.setSerialNumber(attributeValue);
                }
                if ("producingArea".equals(attributeType)) {
                    goodsInfoResult.setProducingArea(attributeValue);
                }
                if ("rotationPicture".equals(attributeType)) {
                    // 修改返回结果，让结果能直接在网页打开
                    String matchChar = "\\";
                    String replaceChar = "/";
                    if (attributeValue.indexOf(matchChar) > 0) {
                        attributeValue = String.format("%s%s", readFileHostIp, attributeValue.replace(matchChar, replaceChar));
                    }
                    goodsInfoResult.getRotationPictureList().add(attributeValue);
                }
                if ("detailsPicture".equals(attributeType)) {
                    // 修改返回结果，让结果能直接在网页打开
                    String matchChar = "\\";
                    String replaceChar = "/";
                    if (attributeValue.indexOf(matchChar) > 0) {
                        attributeValue = String.format("%s%s", readFileHostIp, attributeValue.replace(matchChar, replaceChar));
                    }
                    goodsInfoResult.getDetailsPictureList().add(attributeValue);
                }

                goodsInfoResultMap.put(goodsInfoResult.getId(), goodsInfoResult);
            }
        }

        return new ArrayList<>(goodsInfoResultMap.values());
    }

    /**
     * 根据订单状态code获取message
     *
     * @param orderStatusCode 订单状态code
     * @return 订单状态message
     */
    private String getOrderStatusForAPPByCode(String orderStatusCode) {
        String orderStatusForAPP;
        switch (orderStatusCode) {
            case "I":
                orderStatusForAPP = "1";// 等待付款
                break;
            case "P":
                orderStatusForAPP = "2";// 已付款
                break;
            case "E":
                orderStatusForAPP = "3";// 已失效
                break;
            case "D":
                orderStatusForAPP = "4";// 发货完成
                break;
            case "S":
                orderStatusForAPP = "5";// 订单完成(确认收货)
                break;
            default:
                orderStatusForAPP = "0";// 未知状态
                break;
        }
        return orderStatusForAPP;
    }

    /**
     * 根据支付状态code获取message
     *
     * @param payStatusCode 支付状态code
     * @return 支付状态message
     */
    private String getPayStatusMessageByCode(String payStatusCode) {
        String payStatusMessage;
        switch (payStatusCode) {
            case "W":
                payStatusMessage = "等待支付";
                break;
            case "S":
                payStatusMessage = "成功支付";
                break;
            case "E":
                payStatusMessage = "支付失败";
                break;
            default:
                payStatusMessage = "未知";
                break;
        }
        return payStatusMessage;
    }

    /**
     * 根据支付类型code获取message
     *
     * @param payTypeCode 支付类型code
     * @return 支付类型message
     */
    private String getPayTypeMessageByCode(String payTypeCode) {
        String payTypeMessage;
        switch (payTypeCode) {
            case "W":
                payTypeMessage = "微信支付";
                break;
            case "A":
                payTypeMessage = "支付宝";
                break;
            case "C":
                payTypeMessage = "信用卡";
                break;
            default:
                payTypeMessage = "未知";
                break;
        }
        return payTypeMessage;
    }
}
